# encoding: utf-8

import requests
import json
import time
import datetime
import os
import xlrd
from urllib.parse import quote
from widget.info_box import *
from widget.utils.my_threading_part import MyThreadFunc
# from widget.daoru_page.import_init_page.sqlserver_to_essystem_table__spical_source_init_window import SpicalSourceInitWindow
from widget.db_init.sqlUtils.sqlserverUtils import SqlServerOp
from widget.utils.utils import MyUtils
# from widget.daoru_page.source_init_page.marc_source_init import MarcUtils
import configparser
from pymarc import MARCReader
from widget.daoru_page.import_init_page.import_func.base_func import BaseImportFunc, ProgressSignal, ImportProgressBox


class MarcReadFinishedSignal(QObject):
    '''
    marc读取部分信号
    '''
    # 关闭 marc数据加载中 窗口信号
    marcjzz_box_close_signal = pyqtSignal(name="marcjzzBoxCloseSignal")
    # marc加载完成信号，绑定start_import方法
    start_import_signal = pyqtSignal(list, str, dict, object, name="startImportSignal")


class Marc2Es(BaseImportFunc):
    '''
    sqlserver导入es的方法
    初始化的时候传入 父控件，来源信息字典，目标信息字典
    '''
    def __init__(self, source_dict, target_dict):
        super(Marc2Es, self).__init__(source_dict, target_dict)

    def get_all_data(self, marc_path, operate_dict, RUID, table_parent_widget, related_field_dict=None):
        '''
        读取 marc中的数据
        :return:
        '''

        self.marcjzz_box = InfoBox('marc数据加载中...')
        self.marcjzz_box.show()

        # 此信号用于告知marc数据加载完成，链接start_import导入方法
        self.mrfsig = MarcReadFinishedSignal()
        self.mrfsig.startImportSignal.connect(self.start_import_ziliao)
        self.mrfsig.marcjzzBoxCloseSignal.connect(self.marcjzz_box.close)
        # 加载marc数据线程
        def thread_get_marc():
            '''
            加载marc数据线程，此线程执行完毕后，会把 marc 数据发送到信号中，由 start_import 方法接收并继续执行导入方法
            :return:
            '''
            mc = MarcUtils()
            records = mc.get_marc(marc_path, self.marcjzz_box)
            marc_init_name = self.source_dict['uni']['marc_init_sec']
            fmt_data = mc.format_records(marc_init_name, records, self.marcjzz_box)
            all_data = []
            for i in range(len(fmt_data)):
                if i == 0:
                    continue
                data = []
                for k, name in enumerate(self.source_dict['com']['field_name_list']):
                    for operate in operate_dict['operate_list']:
                        if name == operate['source_code']:
                            data.append(fmt_data[i][k])
                all_data.append(data)
                self.marcjzz_box.label_info.setText('匹配导入项: {0}'.format(i))
                # print('匹配导入项: {0}'.format(i))
            # print('marc加载完毕')
            self.mrfsig.marcjzzBoxCloseSignal.emit()
            # print('fmt_data: {0}'.format(fmt_data))
            # print('all_data: {0}'.format(type(all_data)))
            # 将加载好的marc挂载到当前类上
            self.source_dict['fmt_data'] = all_data
            # 发送marc加载完成信号，调用start_import方法
            self.mrfsig.startImportSignal.emit(all_data, RUID, operate_dict, table_parent_widget)
            # 这里线程不可以马上退出，否则发送的信号将无法被接收
            time.sleep(10)

        self.marc_read_thread = MyThreadFunc(thread_get_marc)
        self.marc_read_thread.start()
        self.marcjzz_box.close_btn.clicked.connect(self.marc_read_thread.stop)

        # print(1/0)
        # return all_data

    # # 导入资料方法 start -------------------------------------------------------------------------
    # def start_import_ziliao(self, all_data, RUID, operate_dict, table_parent_widget):
    #     '''
    #     开始导入(资料部分)
    #     :return:
    #     '''
    #     print('加载导入数据...')
    #
    #     # print(len(all_data))
    #     # print('all_data: {0}'.format(all_data))
    #     # print(1/0)
    #
    #     # 消息盒子start -------------------------------------------
    #     table_parent_widget.progress_box = ImportProgressBox(my_parent=table_parent_widget, sum_num=len(all_data))
    #
    #     # self.table1.parent().progress_box.setWindowFlag(Qt.WindowStaysOnTopHint)
    #     # def stop_run():
    #     #     self.table1.parent().run_flag = False
    #     # 关闭按钮点击，终止线程
    #     # self.table1.parent().progress_box.close_btn.clicked.connect(stop_run)
    #     # 取消按钮点击，关闭窗口
    #     table_parent_widget.progress_box.show()
    #
    #     # 初始化进度条信号实例
    #     self.sig = ProgressSignal()
    #     # 绑定更新进度槽
    #     self.sig.dataChanged.connect(table_parent_widget.progress_box.update_progress)
    #     # 绑定导入结束槽
    #     self.sig.dataFinished.connect(table_parent_widget.progress_box.import_finished)
    #
    #     # 消息盒子end --------------------------------------------
    #
    #     # 展示进度
    #     def start_run():
    #         data_dict_list = []
    #         for i, field in enumerate(all_data):
    #             field = list(field)  # 元祖转字典
    #             data_dict = {}
    #
    #             # 插入一对一元数据 start -----------------------------------------------
    #             for k, item in enumerate(operate_dict['operate_list']):
    #                 # if k != 10100001:
    #                 if not field[k]:
    #                     # print('field[k]: {0}-{1}'.format(k, field[k]))
    #                     if item['target_code'] != '10100001':
    #                         continue
    #                     else:
    #                         field[k] = ' '
    #                         # print(1/0)
    #                 data_dict[item['target_code']] = field[k]
    #
    #             data_dict_list.append(data_dict)
    #             print('data_dict: {0}'.format(data_dict))
    #
    #             if (i + 1) % self.speed == 0 or (i + 1) == len(all_data):
    #                 '''
    #                 {
    #                     "RUID": "任务唯一标识",
    #                     "data": [
    #                       {"RUID":"","10100001":"test","1590001":["1","2"]}
    #                     ]
    #                 }
    #                 '''
    #                 data_dict_encoding = quote(json.dumps(data_dict_list, ensure_ascii=False))
    #                 # print('data_dict_encoding: {0}'.format(data_dict_encoding))
    #
    #                 # 导入数据格式 start --------------------------------
    #                 import_dict = {
    #                     "RUID": RUID,
    #                     "data": data_dict_encoding,
    #                     "appendix": quote(json.dumps([], ensure_ascii=False))
    #                     # "data": [data_dict]
    #                 }
    #                 # 导入数据格式 end --------------------------------
    #
    #                 # 进度(第一次/重新传递数据传递start,最后一批数据传递finish，中间不传递)
    #                 if (i + 1) == self.speed:
    #                     import_dict['schedule'] = 'start'
    #                 if (i + 1) == len(all_data):
    #                     import_dict['schedule'] = 'finish'
    #
    #                 # url = qApp.cx_es_db_ip + '/import/importdata'
    #                 # url = qApp.cx_es_db_ip + '/import/importdataorappendix'
    #                 url = qApp.cx_es_db_ip + '/dataprocessingapi/dataimport/importdataorappendix.action'
    #                 print('请求导入。。。')
    #                 print('当前任务RUID:{0}'.format(RUID))
    #                 res = requests.post(url, data=import_dict, verify=False)
    #                 # print('请求返回。。。')
    #                 print('后台返回值：{0}'.format(res.status_code))
    #                 print('当前进度： {0}'.format(i))
    #
    #                 if res.status_code == 500:
    #                     print('报错信息{0}：'.format(res.text))
    #                     return
    #                     # return_dict = {'state': 500}
    #                     # return return_dict
    #                 field_dict = json.loads(res.text) if res.text else None
    #                 # print(field_dict)
    #                 # 请求结果状态
    #                 state = field_dict['cxajaxrc']
    #                 print('state: {0}'.format(state))
    #                 if state == '-1':
    #                     self.add_err_log('资料进度：{0}；请求成功，返回-1，报错信息：{1}'.format(i, field_dict[
    #                         'cxajaxerrmsg'] if 'cxajaxerrmsg' in field_dict else ''))
    #                     print('请求成功，返回错误：{0}'.format(field_dict['cxajaxerrmsg']))
    #                 if state == '0':
    #                     # returnvalue = field_dict['returnvalue']
    #                     # if 'cxajaxloglist' in returnvalue:
    #                     #     self.add_err_log('资料进度：{0}；请求成功，返回0，报错信息：{1}'.format(i, str(
    #                     #         returnvalue['cxajaxloglist'] if 'cxajaxloglist' in returnvalue else '')))
    #
    #                     # 插入日志 start -----------------------------------------------------
    #                     try:
    #                         returnvalue = field_dict['returnvalue']
    #                         if 'cxajaxloglist' in returnvalue:
    #                             log_str = ''
    #                             for u in range(len(returnvalue['cxajaxloglist'])):
    #                                 cur_num = (i + 1) - 25 + (u + 1)
    #                                 log_str += '资料进度：{0}-{1}；请求成功，返回0，导入信息：{2}\n'.format(
    #                                     cur_num,
    #                                     data_dict_list[u]['10100001'],
    #                                     str(returnvalue['cxajaxloglist'][u] if returnvalue['cxajaxloglist'][u] else '导入成功')
    #                                 )
    #                             self.add_err_log(log_str)
    #                     except Exception as e:
    #                         print(e)
    #                     # 插入日志 end -----------------------------------------------------
    #
    #                     print('请求成功，返回正确')
    #                     # self.add_err_log('资料进度：{0}；请求成功，返回0，报错信息：{1}'.format(i, str(field_dict['cxajaxloglist'] if 'cxajaxloglist' in field_dict else '')))
    #                     # print('请求成功，返回正确')
    #                     # print('data_dict_encoding: {0}'.format(data_dict_encoding))
    #                     # print('data_dict: {0}'.format(json.dumps(data_dict_list, ensure_ascii=False)))
    #                     # print(111111111111111111111111111111111111111111)
    #                     success_num = field_dict['returnvalue']["success"]
    #                     fail_num = field_dict['returnvalue']["error"]
    #                     # cal_signal = pyqtSignal(np.ndarray, np.ndarray)
    #
    #                     # self.download_proess_signal.emit(int(proess))
    #
    #                     # 发射进度条更新信号
    #                     self.sig.dataChanged.emit(success_num, fail_num, i + 1)
    #
    #                     # self.table1.parent().progress_box.update_progress(success_num, fail_num)
    #
    #                     # print('成功{0}条'.format(success_num))
    #                     # print('失败{0}条'.format(fail_num))
    #                     # return_dict = {'state': -1, 'success_num': success_num, 'fail_num': fail_num}
    #                     # return return_dict
    #
    #                 # 一百天传完后，清空队列，再传下一百条
    #                 data_dict_list = []
    #
    #         # 发射导入结束信号
    #         self.sig.dataFinished.emit(True)
    #
    #     # _thread.start_new_thread(start_run, ())
    #
    #     self.import_thread = MyThreadFunc(start_run)
    #     self.import_thread.start()
    #     # 关闭按钮点击，终止线程
    #     table_parent_widget.progress_box.close_btn.clicked.connect(self.import_thread.stop)
    #     table_parent_widget.progress_box.cancel_btn.clicked.connect(table_parent_widget.progress_box.close_btn.click)
    # # 导入资料方法 end -------------------------------------------------------------------------


class MarcUtils(object):
    '''
    marc数据操作类
    '''

    @classmethod
    def get_marc(self, fpath, info_box, num=None):
        '''
        读取 marc
        :param fpath:
        :param num:
        :return:
        '''
        # ma = MarcUtils()
        # fpath = r'D:\marc20171218.iso'
        # ma.daorumarc(fpath)

        # with open(fpath, 'rb') as fh:
        #     reader = MARCReader(fh)
        #     for record in reader:
        #         print(record.as_json(indent=2))

        count = 0
        headings = set()
        headings.add('LDR')
        records = []
        # with open(fpath, 'rb') as marc_file:
        #    utf8_handling = 'replace' if force_utf8 else 'strict'
        #    file_encoding="UTF-8"
        #    reader = MARCReader(marc_file)
        print(fpath)
        reader = MARCReader(open(fpath, 'rb'), file_encoding="utf-8", utf8_handling='replace')

        # print('sum(1 for _ in reader): {0}'.format(sum(1 for _ in reader)))
        # print(list(reader))
        # for i, red in reader:
        #     print(i, red)
        # print(1/0)
        for record in reader:
            if record == "eof":
                break
            try:
                rec_dict = {'LDR': record.leader}
                rheadings = []
                for field in record.fields:
                    heading = field.tag
                    rheadings.append(heading)

                    if field.is_control_field():
                        rec_dict[heading] = field.value()
                        headings.add(heading)

                    if hasattr(field, 'subfields'):
                        i1 = field.indicator1.replace(' ', '\\')
                        i2 = field.indicator1.replace(' ', '\\')
                        heading = '{0} {1}{2}'.format(heading, i1, i2)

                        # Split subfields
                        c = [code for code in field.subfields[::2]]
                        v = [value for value in field.subfields[1::2]]
                        subfields = [(c[i], v[i]) for i in range(len(c))]
                        for s in subfields:
                            subheading = '{0} ${1}'.format(heading, s[0])
                            n = rheadings.count(field.tag)
                            if n > 1:
                                subheading = '{0} [{1}]'.format(subheading, n)
                            rec_dict[subheading] = s[1]
                            headings.add(subheading)

                records.append(rec_dict)

                if num and count >= num - 1:
                    break
            except Exception as ex:
                print("error_num: {0}".format(count))
                print("error_reson: {0}".format(ex))

            count = count + 1
            info_box.label_info.setText('正在读取marc: {0}'.format(count))
            # print('正在读取marc: {0}'.format(count))

        # print("readover")
        # print(records)
        # data = [headings] + [[r.get(h, '') for h in headings] for r in records]
        # print(data)
        # print(ecords)

        return records

    @classmethod
    def format_records(self, marc_init_sec, records, info_box):
        row1 = []
        cf = self.get_init_file_cf()
        # secs = cf.sections()
        # print(secs)
        field_list_str = cf.get(marc_init_sec, "field_list")
        # with open('d:\marcfieldtest.json', 'r', encoding='UTF-8') as load_ini:
        # load_field = json.load(kl)
        field_list = json.loads(field_list_str)
        # print(field_list)
        # print(type(field_list))
        # print(1/0)
        for rows in field_list:
            chekyes = rows["import"]
            if chekyes != 0:
                row1.append(
                    "{0} {1} {2} {3}   ({4})".format(rows["field"], rows["indicator1"] if rows["indicator1"] else '\\',
                                                     rows["indicator2"] if rows["indicator2"] else '\\',
                                                     rows["subfield"], rows['fieldname']))
        dictview = [row1]
        fmt_count = 0
        for r in records:
            rowls = []
            find = False
            for h in row1:
                for f in r:
                    # if f[0:3] == h[0:3] and f[len(f) - 2:] == h[len(h) - 2:]:
                    if f[0:3] == h.split(' ')[0] and f[len(f) - 2:] == h.split(' ')[3]:
                        rowls.append(r.get(f))
                        find = True
                        break
                if find == False: rowls.append("")
                find = False
            dictview.append(rowls)
            fmt_count += 1
            info_box.label_info.setText('正在格式化marc: {0}'.format(fmt_count))
            # print('正在格式化marc: {0}'.format(fmt_count))
        return dictview

    @classmethod
    def get_init_file_cf(self):
        cf = configparser.ConfigParser()
        print(qApp.cx_project_root.replace('\\', '/') + '/init_file/init/marcfield.ini')
        cf.read(qApp.cx_project_root.replace('\\', '/') + '/init_file/init/marcfield.ini')
        return cf

    @classmethod
    def init_write(self, cf):
        cf.write(open(qApp.cx_project_root.replace('\\', '/') + r'/init_file/init/marcfield.ini', "w"))












# # encoding: utf-8
#
# import xlrd
# from widget.info_box import *
# from widget.daoru_page.import_init_page.import_func.excl_to_es_func import Excl2Es
# from widget.daoru_page.source_init_page.marc_source_init import MarcUtils
# from widget.utils.my_threading_part import MyThreadFunc
#
#
# class MarcReadSignal(QObject):
#     '''
#     进度条自定义信号
#     '''
#     # 导入完成信号
#     format_data_signal = pyqtSignal(list, name="FormatDataSignal")
#
#
# # class MarcProgressBox(ProgressBox):
# #     def update_read_progress(self, cur_num):
# #         '''
# #         更新进度条的接收槽
# #         :param success_num:
# #         :param fail_num:
# #         :return:
# #         '''
# #         self.label_info1.setText('读取marc数据中...')
# #         step = int(cur_num / self.sum_num * 100)
# #         print('step: {0}-{1}'.format(step, type(step)))
# #         self.pbar.setValue(step)
#
# class Marc2Es(Excl2Es):
#     '''
#     sqlserver导入es的方法
#     初始化的时候传入 父控件，来源信息字典，目标信息字典
#     '''
#     def __init__(self, source_dict, target_dict, cur_table):
#         super().__init__(source_dict, target_dict, cur_table)
#
#     def get_all_data(self, marc_path):
#         '''
#         读取 marc中的数据
#         :return:
#         '''
#         # todo
#         # print(marc_path)
#         # print(1/0)
#         # self.table1.parent().progress_box = ProgressBox(len(all_data))
#         # self.marcdqz_box = InfoBox('marc数据读取中...')
#         # self.marcdqz_box.show()
#         self.marcjzz_box = InfoBox('marc数据加载中...')
#         self.marcjzz_box.show()
#         # 绑定更新进度槽
#         self.sig = MarcReadSignal()
#         self.sig.FormatDataSignal.connect(self.start_import_ziliao)
#
#         mc = MarcUtils()
#         records = mc.get_marc(marc_path, 10)
#         marc_init_name = qApp.cx_src['uni']['marc_init_sec']
#         fmt_data = mc.format_records(marc_init_name, records)
#         # 发射格式化好的marc数据, 如果有数据，那么继续执行程序，否则提示报错信息
#         self.marcjzz_box.close()
#         print('fmt_data: {0}'.format(fmt_data))
#         return fmt_data
